<html><head><meta charset="utf-8"/><title>数据类型和变量</title></head><body><h1>数据类型和变量</h1><div class="x-wiki-content x-main-content">
 <h3>
  数据类型
 </h3>
 <p>
  计算机顾名思义就是可以做数学计算的机器，因此，计算机程序理所当然地可以处理各种数值。但是，计算机能处理的远不止数值，还可以处理文本、图形、音频、视频、网页等各种各样的数据，不同的数据，需要定义不同的数据类型。在JavaScript中定义了以下几种数据类型：
 </p>
 <h4>
  Number
 </h4>
 <p>
  JavaScript不区分整数和浮点数，统一用Number表示，以下都是合法的Number类型：
 </p>
 <pre><code>123; // 整数123
0.456; // 浮点数0.456
1.2345e3; // 科学计数法表示1.2345x1000，等同于1234.5
-99; // 负数
NaN; // NaN表示Not a Number，当无法计算结果时用NaN表示
Infinity; // Infinity表示无限大，当数值超过了JavaScript的Number所能表示的最大值时，就表示为Infinity
</code></pre>
 <p>
  计算机由于使用二进制，所以，有时候用十六进制表示整数比较方便，十六进制用0x前缀和0-9，a-f表示，例如：
  <code>
   0xff00
  </code>
  ，
  <code>
   0xa5b4c3d2
  </code>
  ，等等，它们和十进制表示的数值完全一样。
 </p>
 <p>
  Number可以直接做四则运算，规则和数学一致：
 </p>
 <pre><code>1 + 2; // 3
(1 + 2) * 5 / 2; // 7.5
2 / 0; // Infinity
0 / 0; // NaN
10 % 3; // 1
10.5 % 3; // 1.5
</code></pre>
 <p>
  注意
  <code>
   %
  </code>
  是求余运算。
 </p>
 <h4>
  字符串
 </h4>
 <p>
  字符串是以单引号'或双引号"括起来的任意文本，比如
  <code>
   'abc'
  </code>
  ，
  <code>
   "xyz"
  </code>
  等等。请注意，
  <code>
   ''
  </code>
  或
  <code>
   ""
  </code>
  本身只是一种表示方式，不是字符串的一部分，因此，字符串
  <code>
   'abc'
  </code>
  只有
  <code>
   a
  </code>
  ，
  <code>
   b
  </code>
  ，
  <code>
   c
  </code>
  这3个字符。
 </p>
 <h4>
  布尔值
 </h4>
 <p>
  布尔值和布尔代数的表示完全一致，一个布尔值只有
  <code>
   true
  </code>
  、
  <code>
   false
  </code>
  两种值，要么是
  <code>
   true
  </code>
  ，要么是
  <code>
   false
  </code>
  ，可以直接用
  <code>
   true
  </code>
  、
  <code>
   false
  </code>
  表示布尔值，也可以通过布尔运算计算出来：
 </p>
 <pre><code>true; // 这是一个true值
false; // 这是一个false值
2 &gt; 1; // 这是一个true值
2 &gt;= 3; // 这是一个false值
</code></pre>
 <p>
  <code>
   &amp;&amp;
  </code>
  运算是与运算，只有所有都为
  <code>
   true
  </code>
  ，
  <code>
   &amp;&amp;
  </code>
  运算结果才是
  <code>
   true
  </code>
  ：
 </p>
 <pre><code>true &amp;&amp; true; // 这个&amp;&amp;语句计算结果为true
true &amp;&amp; false; // 这个&amp;&amp;语句计算结果为false
false &amp;&amp; true &amp;&amp; false; // 这个&amp;&amp;语句计算结果为false
</code></pre>
 <p>
  <code>
   ||
  </code>
  运算是或运算，只要其中有一个为
  <code>
   true
  </code>
  ，
  <code>
   ||
  </code>
  运算结果就是
  <code>
   true
  </code>
  ：
 </p>
 <pre><code>false || false; // 这个||语句计算结果为false
true || false; // 这个||语句计算结果为true
false || true || false; // 这个||语句计算结果为true
</code></pre>
 <p>
  <code>
   !
  </code>
  运算是非运算，它是一个单目运算符，把
  <code>
   true
  </code>
  变成
  <code>
   false
  </code>
  ，
  <code>
   false
  </code>
  变成
  <code>
   true
  </code>
  ：
 </p>
 <pre><code>! true; // 结果为false
! false; // 结果为true
! (2 &gt; 5); // 结果为true
</code></pre>
 <p>
  布尔值经常用在条件判断中，比如：
 </p>
 <pre><code>var age = 15;
if (age &gt;= 18) {
    alert('adult');
} else {
    alert('teenager');
}
</code></pre>
 <h3>
  比较运算符
 </h3>
 <p>
  当我们对Number做比较时，可以通过比较运算符得到一个布尔值：
 </p>
 <pre><code>2 &gt; 5; // false
5 &gt;= 2; // true
7 == 7; // true
</code></pre>
 <p>
  实际上，JavaScript允许对任意数据类型做比较：
 </p>
 <pre><code>false == 0; // true
false === 0; // false
</code></pre>
 <p>
  要特别注意相等运算符
  <code>
   ==
  </code>
  。JavaScript在设计时，有两种比较运算符：
 </p>
 <p>
  第一种是
  <code>
   ==
  </code>
  比较，它会自动转换数据类型再比较，很多时候，会得到非常诡异的结果；
 </p>
 <p>
  第二种是
  <code>
   ===
  </code>
  比较，它不会自动转换数据类型，如果数据类型不一致，返回
  <code>
   false
  </code>
  ，如果一致，再比较。
 </p>
 <p>
  由于JavaScript这个设计缺陷，
  <em>
   不要
  </em>
  使用
  <code>
   ==
  </code>
  比较，始终坚持使用
  <code>
   ===
  </code>
  比较。
 </p>
 <p>
  另一个例外是
  <code>
   NaN
  </code>
  这个特殊的Number与所有其他值都不相等，包括它自己：
 </p>
 <pre><code>NaN === NaN; // false
</code></pre>
 <p>
  唯一能判断
  <code>
   NaN
  </code>
  的方法是通过
  <code>
   isNaN()
  </code>
  函数：
 </p>
 <pre><code>isNaN(NaN); // true
</code></pre>
 <p>
  最后要注意浮点数的相等比较：
 </p>
 <pre><code>1 / 3 === (1 - 2 / 3); // false
</code></pre>
 <p>
  这不是JavaScript的设计缺陷。浮点数在运算过程中会产生误差，因为计算机无法精确表示无限循环小数。要比较两个浮点数是否相等，只能计算它们之差的绝对值，看是否小于某个阈值：
 </p>
 <pre><code>Math.abs(1 / 3 - (1 - 2 / 3)) &lt; 0.0000001; // true
</code></pre>
 <h4>
  null和undefined
 </h4>
 <p>
  <code>
   null
  </code>
  表示一个“空”的值，它和
  <code>
   0
  </code>
  以及空字符串
  <code>
   ''
  </code>
  不同，
  <code>
   0
  </code>
  是一个数值，
  <code>
   ''
  </code>
  表示长度为0的字符串，而
  <code>
   null
  </code>
  表示“空”。
 </p>
 <p>
  在其他语言中，也有类似JavaScript的
  <code>
   null
  </code>
  的表示，例如Java也用
  <code>
   null
  </code>
  ，Swift用
  <code>
   nil
  </code>
  ，Python用
  <code>
   None
  </code>
  表示。但是，在JavaScript中，还有一个和
  <code>
   null
  </code>
  类似的
  <code>
   undefined
  </code>
  ，它表示“未定义”。
 </p>
 <p>
  JavaScript的设计者希望用
  <code>
   null
  </code>
  表示一个空的值，而
  <code>
   undefined
  </code>
  表示值未定义。事实证明，这并没有什么卵用，区分两者的意义不大。大多数情况下，我们都应该用
  <code>
   null
  </code>
  。
  <code>
   undefined
  </code>
  仅仅在判断函数参数是否传递的情况下有用。
 </p>
 <h4>
  数组
 </h4>
 <p>
  数组是一组按顺序排列的集合，集合的每个值称为元素。JavaScript的数组可以包括任意数据类型。例如：
 </p>
 <pre><code>[1, 2, 3.14, 'Hello', null, true];
</code></pre>
 <p>
  上述数组包含6个元素。数组用
  <code>
   []
  </code>
  表示，元素之间用
  <code>
   ,
  </code>
  分隔。
 </p>
 <p>
  另一种创建数组的方法是通过
  <code>
   Array()
  </code>
  函数实现：
 </p>
 <pre><code>new Array(1, 2, 3); // 创建了数组[1, 2, 3]
</code></pre>
 <p>
  然而，出于代码的可读性考虑，强烈建议直接使用
  <code>
   []
  </code>
  。
 </p>
 <p>
  数组的元素可以通过索引来访问。请注意，索引的起始值为
  <code>
   0
  </code>
  ：
 </p>
 <pre><code>var arr = [1, 2, 3.14, 'Hello', null, true];
arr[0]; // 返回索引为0的元素，即1
arr[5]; // 返回索引为5的元素，即true
arr[6]; // 索引超出了范围，返回undefined
</code></pre>
 <h4>
  对象
 </h4>
 <p>
  JavaScript的对象是一组由键-值组成的无序集合，例如：
 </p>
 <pre><code>var person = {
    name: 'Bob',
    age: 20,
    tags: ['js', 'web', 'mobile'],
    city: 'Beijing',
    hasCar: true,
    zipcode: null
};
</code></pre>
 <p>
  JavaScript对象的键都是字符串类型，值可以是任意数据类型。上述
  <code>
   person
  </code>
  对象一共定义了6个键值对，其中每个键又称为对象的属性，例如，
  <code>
   person
  </code>
  的
  <code>
   name
  </code>
  属性为
  <code>
   'Bob'
  </code>
  ，
  <code>
   zipcode
  </code>
  属性为
  <code>
   null
  </code>
  。
 </p>
 <p>
  要获取一个对象的属性，我们用
  <code>
   对象变量.属性名
  </code>
  的方式：
 </p>
 <pre><code>person.name; // 'Bob'
person.zipcode; // null
</code></pre>
 <h3>
  变量
 </h3>
 <p>
  变量的概念基本上和初中代数的方程变量是一致的，只是在计算机程序中，变量不仅可以是数字，还可以是任意数据类型。
 </p>
 <p>
  变量在JavaScript中就是用一个变量名表示，变量名是大小写英文、数字、
  <code>
   $
  </code>
  和
  <code>
   _
  </code>
  的组合，且不能用数字开头。变量名也不能是JavaScript的关键字，如
  <code>
   if
  </code>
  、
  <code>
   while
  </code>
  等。申明一个变量用
  <code>
   var
  </code>
  语句，比如：
 </p>
 <pre><code>var a; // 申明了变量a，此时a的值为undefined
var $b = 1; // 申明了变量$b，同时给$b赋值，此时$b的值为1
var s_007 = '007'; // s_007是一个字符串
var Answer = true; // Answer是一个布尔值true
var t = null; // t的值是null
</code></pre>
 <p>
  变量名也可以用中文，但是，请不要给自己找麻烦。
 </p>
 <p>
  在JavaScript中，使用等号
  <code>
   =
  </code>
  对变量进行赋值。可以把任意数据类型赋值给变量，同一个变量可以反复赋值，而且可以是不同类型的变量，但是要注意只能用
  <code>
   var
  </code>
  申明一次，例如：
 </p>
 <pre><code>var a = 123; // a的值是整数123
a = 'ABC'; // a变为字符串
</code></pre>
 <p>
  这种变量本身类型不固定的语言称之为动态语言，与之对应的是静态语言。静态语言在定义变量时必须指定变量类型，如果赋值的时候类型不匹配，就会报错。例如Java是静态语言，赋值语句如下：
 </p>
 <pre><code>int a = 123; // a是整数类型变量，类型用int申明
a = "ABC"; // 错误：不能把字符串赋给整型变量
</code></pre>
 <p>
  和静态语言相比，动态语言更灵活，就是这个原因。
 </p>
 <p>
  请不要把赋值语句的等号等同于数学的等号。比如下面的代码：
 </p>
 <pre><code>var x = 10;
x = x + 2;
</code></pre>
 <p>
  如果从数学上理解
  <code>
   x = x + 2
  </code>
  那无论如何是不成立的，在程序中，赋值语句先计算右侧的表达式
  <code>
   x + 2
  </code>
  ，得到结果
  <code>
   12
  </code>
  ，再赋给变量
  <code>
   x
  </code>
  。由于
  <code>
   x
  </code>
  之前的值是
  <code>
   10
  </code>
  ，重新赋值后，
  <code>
   x
  </code>
  的值变成
  <code>
   12
  </code>
  。
 </p>
 <p>
  要显示变量的内容，可以用
  <code>
   console.log(x)
  </code>
  ，打开Chrome的控制台就可以看到结果。
 </p>
 <pre><code class="language-x-javascript">// 打印变量x
----
var x = 100;
console.log(x);
</code></pre>
 <p>
  使用
  <code>
   console.log()
  </code>
  代替
  <code>
   alert()
  </code>
  的好处是可以避免弹出烦人的对话框。
 </p>
 <h3>
  strict模式
 </h3>
 <p>
  JavaScript在设计之初，为了方便初学者学习，并不强制要求用
  <code>
   var
  </code>
  申明变量。这个设计错误带来了严重的后果：如果一个变量没有通过
  <code>
   var
  </code>
  申明就被使用，那么该变量就自动被申明为全局变量：
 </p>
 <pre><code>i = 10; // i现在是全局变量
</code></pre>
 <p>
  在同一个页面的不同的JavaScript文件中，如果都不用
  <code>
   var
  </code>
  申明，恰好都使用了变量
  <code>
   i
  </code>
  ，将造成变量
  <code>
   i
  </code>
  互相影响，产生难以调试的错误结果。
 </p>
 <p>
  使用
  <code>
   var
  </code>
  申明的变量则不是全局变量，它的范围被限制在该变量被申明的函数体内（函数的概念将稍后讲解），同名变量在不同的函数体内互不冲突。
 </p>
 <p>
  为了修补JavaScript这一严重设计缺陷，ECMA在后续规范中推出了strict模式，在strict模式下运行的JavaScript代码，强制通过
  <code>
   var
  </code>
  申明变量，未使用
  <code>
   var
  </code>
  申明变量就使用的，将导致运行错误。
 </p>
 <p>
  启用strict模式的方法是在JavaScript代码的第一行写上：
 </p>
 <pre><code>'use strict';
</code></pre>
 <p>
  这是一个字符串，不支持strict模式的浏览器会把它当做一个字符串语句执行，支持strict模式的浏览器将开启strict模式运行JavaScript。
 </p>
 <p>
  来测试一下你的浏览器是否能支持strict模式：
 </p>
 <pre><code class="language-x-javascript">'use strict';
// 如果浏览器支持strict模式，
// 下面的代码将报ReferenceError错误:
----
abc = 'Hello, world';
console.log(abc);
</code></pre>
 <p>
  运行代码，如果浏览器报错，请修复后再运行。如果浏览器不报错，说明你的浏览器太古老了，需要尽快升级。
 </p>
 <p>
  不用
  <code>
   var
  </code>
  申明的变量会被视为全局变量，为了避免这一缺陷，所有的JavaScript代码都应该使用strict模式。我们在后面编写的JavaScript代码将全部采用strict模式。
 </p>
</div>
</body></html>